<?php
Junction_FileCabinet::using("Junction_Libs_Catalog");
Junction_FileCabinet::using("Junction_Db_Common_Service");
//Junction_FileCabinet::package("Junction_Db_Common");
//Junction_FileCabinet::package("Junction_Db_Adodb");

Junction_FileCabinet::get(Junction_Libs_Catalog::fetch("adodb/adodb.inc.php"));
Junction_FileCabinet::get(Junction_Libs_Catalog::fetch("adodb/adodb-exceptions.inc.php"));

/**
 * Implements the common service which acts as the gatekeeper 
 * for the database
 *
 * @package junction.db.adodb
 * @author Alexander Schearer <aas11@duke.edu>
 */
class Junction_Db_Adodb_Service implements Junction_Db_Common_Service {
	
	/**
	 * Adodb connection
	 *
	 * @var ADOConnection
	 */
	private $_dbh;
	
	/**
	 * Adodb adapter constructor
	 * 
	 * @param string $dsn a valid Adodb data source name.
	 * @throws Junction_Db_Common_SqlException
	 */
	public function __construct($dsn) {
		try {
			$this->_dbh = NewADOConnection($dsn);
			$this->_dbh->SetFetchMode(ADODB_FETCH_ASSOC);
		} catch (Exception $e) {
			throw new Junction_Db_Common_SqlException($e->getMessage(), $dsn);
		}
	}
	
	/**
	 * Turn debugging on or off
	 * 
	 * @see Junction_Db_Common_Service::debug()
	 */
	public function debug($bool) {
		$this->_dbh->debug = $bool;
	}
	
	/**
	 * Perform a query which effects the database
	 * 
	 * @see Junction_Db_Common_Service::save()
	 *
	 * @throws Junction_Db_Common_SqlException
	 * @param String $query
	 * @return boolean
	 */
	public function save($query) {
		try {
			return ($this->_dbh->Execute($query) !== false);
		} catch (Exception $e) {
			throw new Junction_Db_Common_SqlException($e->getMessage(), $query);
		}
	}
	
	/**
	 * Perform a query which returns a result set
	 * 
	 * @see Junction_Db_Common_Service::select()
	 *
	 * @throws Junction_Db_Common_SqlException
	 * @param String $query
	 * @return Junction_Db_Common_ResultSet
	 */
	public function select($query) {
		try {
			return new Junction_Db_Adodb_ResultSet($this->_dbh->Execute($query), $query);
		} catch (Exception $e) {
			throw new Junction_Db_Common_SqlException($e->getMessage(), $query);
		}
	}
	
	/**
	 * Construct a prepared query which can be re-used with different values
	 * 
	 * @see Junction_Db_Common_Service::prepare()
	 * 
	 * @return Junction_Db_Common_PreparedStatement
	 */
	public function prepare($query) {
		return new Junction_Db_Adodb_PreparedStatement($this->_dbh, $this->_dbh->Prepare($query));
	}
	
	public function escape($data) {
		return $this->_dbh->escape($data);
	}
	
	/**
	 * Returns the number of rows affected by the previous query
	 * 
	 * @see Junction_Db_Common_Service::affectedRows()
	 *
	 * @return int
	 */
	public function affectedRows() {
		return $this->_dbh->Affected_Rows();
	}
	
	/**
	 * Returns the key for the previously inserted row
	 * 
	 * @see Junction_Db_Common_Service::lastInsertId()
	 *
	 * @return int
	 */
	public function lastInsertId() {
		return $this->_dbh->Insert_ID();
	}
	
	/**
	 * Enter into transactional mode
	 *
	 * @see Junction_Db_Common_Service::startTransaction()
	 * 
	 * @return boolean
	 */
	public function startTransaction() {
		$this->_dbh->StartTrans();
		return true;
	}
	
	/**
	 * Exit transactional mode committing any queries
	 *
	 * @see Junction_Db_Common_Service::stopTransaction()
	 * 
	 * @return boolean
	 */
	public function stopTransaction() {
		return $this->_dbh->CompleteTrans();
	}
}
?>